package com.mz.demo.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.mz.demo.dao.*;
import com.mz.demo.entity.*;
import com.mz.demo.entity.vo.UserQuery;
import com.mz.demo.entity.vo.UserVo;
import com.mz.demo.service.UserService;
import com.mz.demo.utils.entity.PaginationVo;
import jakarta.annotation.Resource;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;

@Service
public class UserServiceImpl implements UserService {

    @Resource
    private UserMapper userMapper;
    @Resource
    private UserRoleMapper userRoleMapper;
    @Resource
    private RoleMapper roleMapper;
    @Resource
    private BCryptPasswordEncoder bCryptPasswordEncoder;
    @Resource
    private RolePermissionMapper rolePermissionMapper;
    @Resource
    private PermissionMapper permissionMapper;

    @Override
    @Transactional
    public void addUser(UserVo userVo) {

        userVo.setUserId(null);
        userVo.setPassword(bCryptPasswordEncoder.encode(userVo.getPassword()));
        SysUser sysUser = userVoToSysUser(userVo);
        userMapper.insert(sysUser);

        List<Long> roleIdList = userVo.getRoleIdList();
        if( roleIdList == null || roleIdList.size() == 0 ){
            return;
        }

        for( Long roleId : roleIdList ){
            SysUserRole sysUserRole = new SysUserRole()
                    .setRoleId(roleId)
                    .setUserId(userVo.getUserId());
            userRoleMapper.insert(sysUserRole);
        }
        return;
    }

    @Override
    public IPage getUserPagination(PaginationVo paginationVo, UserQuery userQuery) {

        IPage page = new Page( paginationVo.getPageSize(), paginationVo.getPageSize() );
        LambdaQueryWrapper<SysUser> lqs = new LambdaQueryWrapper<>();
        lqs.orderByDesc(SysUser::getCreateTime);

        //先获取用户
        userMapper.selectPage(page, lqs);

        //然后获取用户的所有权限
        List<SysUser> userList = page.getRecords();
        List<SysUser> tempList = userList.stream().map( item->{
             List<SysRole> roleList = getUserRoleList( item.getId() );
             item.setRoleList(roleList);
            return item;
        }).collect(Collectors.toList());
        page.setRecords(tempList);
        return page;
    }

    @Override
    public SysUser getUserDetailById(Long userId) {

        SysUser sysUser = userMapper.selectById(userId);
        List<SysRole> userRoleList = getUserRoleList(userId);
        sysUser.setRoleList(userRoleList);
        return sysUser;
    }

    @Override
    @Transactional
    public void updateUserInfo(UserVo userVo) {
        SysUser sysUser = userVoToSysUser(userVo);
        userMapper.updateById(sysUser);

        List<Long> roleIdList = userVo.getRoleIdList();
        //移除原来的所有角色
        LambdaQueryWrapper<SysUserRole> lqs = new LambdaQueryWrapper<>();
        lqs.eq(SysUserRole::getUserId, userVo.getUserId());
         userRoleMapper.delete( lqs );

         //如果没有新设置权限，则直接结束。
         if( roleIdList == null || roleIdList.size() == 0 ){
            return;
         }

         //设置新的角色权限。
        for( Long roleId : roleIdList ){
            SysUserRole sysUserRole = new SysUserRole()
                    .setRoleId(roleId)
                    .setUserId(userVo.getUserId());
            userRoleMapper.insert(sysUserRole);
        }
        return;
    }

    @Override
    @Transactional
    public void removeUserById(Long userId) {
        userMapper.deleteById(userId);
    }


    /**
     * 根据 用户id 获取所有角色
     * */
    @Override
    public List<SysRole> getUserRoleList(Long userId) {

        LambdaQueryWrapper<SysUserRole> userRoleLqs = new LambdaQueryWrapper<>();
        userRoleLqs.eq( SysUserRole::getUserId, userId );
        List<SysUserRole> userRoleList = userRoleMapper.selectList( userRoleLqs );
        if( userRoleList == null || userRoleList.size() == 0 ){
            return  new ArrayList<>();
        }

        Set roleIdSet = userRoleList.stream().map(item->item.getRoleId()).collect(Collectors.toSet());
        List<SysRole> roleList = roleMapper.selectBatchIds(roleIdSet);
        return roleList;
    }

    @Override
    public List<SysPermission> getUserPermissionList(Long userId) {

        //获取当前用户对应的权限列表
        List<SysRole> roleList =  getUserRoleList(userId);
        Set<Long> roleIdList = roleList.stream().map(item->item.getId()).collect(Collectors.toSet());
        if( roleIdList == null || roleIdList.size() == 0 ){
            return  new ArrayList<>();
        }
        LambdaQueryWrapper<SysRolePermission> lqs = new LambdaQueryWrapper<>();
        lqs.in(SysRolePermission::getRoleId, roleIdList);
        List<SysRolePermission> rolePermissions = rolePermissionMapper.selectList(lqs);
        if( rolePermissions == null || rolePermissions.size() == 0 ){
            return  new ArrayList<>();
        }

        Set<Long> permissionIdSet = rolePermissions.stream().map(item->item.getPermissionId()).collect(Collectors.toSet());
        List<SysPermission> permissionList = permissionMapper.selectBatchIds(permissionIdSet);

        return permissionList;
    }

    private SysUser userVoToSysUser( UserVo userVo ){

        SysUser sysUser = new SysUser();
        sysUser.setId(userVo.getUserId())
                .setUsername(userVo.getUsername())
                .setNickname(userVo.getNickname())
                .setPassword(userVo.getPassword())
                .setAge(userVo.getAge())
                .setGender(userVo.getGender());
        return sysUser;
    }
}
